﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;

namespace Matthew
{
    public partial class FrmInvoice : Form
    {
        public FrmInvoice()
        {
            InitializeComponent();
            dgvOrders.AutoGenerateColumns = false;
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            this.Hide();
            AllFormClass.FormMenu.Show();
        }

        private void btnView_Click(object sender, EventArgs e)
        {
            List<Order> orderList = DBManager.GetAllOrders();
            dgvOrders.DataSource = orderList;

            if (orderList != null)
            {
                lblInvoiceID.Show();
                txtInvoiceID.Show();
                btnIssueInvoice.Show();
                btnDetails.Show();
                generateRandomInvoiceID();
            }
            else
            {
                MessageBox.Show("No orders were retrieved.\n\nThis could be due to zero pending orders at the moment.\nIt could also be due to a database connection error.\nPlease check your database connection settings.", "No pending orders");
                lblInvoiceID.Show();
                txtInvoiceID.Show();
                btnIssueInvoice.Hide();
                btnDetails.Hide();
            }
        }

        private void btnIssueInvoice_Click(object sender, EventArgs e)
        {
            DataGridViewRow currentRow = dgvOrders.SelectedRows[0];
            Order order = (Order)currentRow.DataBoundItem;
            
            issueInvoice(order, txtInvoiceID.Text);
        }

        private void btnDetails_Click(object sender, EventArgs e)
        {
            DataGridViewRow currentRow = dgvOrders.SelectedRows[0];
            AllFormClass.FormInvoice2.order = (Order)currentRow.DataBoundItem;
            AllFormClass.FormInvoice2.invoiceID = txtInvoiceID.Text;

            this.Hide();
            AllFormClass.FormInvoice2.Show();
            AllFormClass.FormInvoice2.Initialize();
        }

        public bool issueInvoice(Order order, string invoiceID)
        {
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string invoiceErrorMsg = checkInvoice(order.OrderID, invoiceID);
                if (invoiceErrorMsg == "")
                {
                    // SAX approach
                    try
                    {
                        int totalQuantity = 0;
                        double shippingCharges, totalCost = 0;

                        XmlWriterSettings settings = new XmlWriterSettings();
                        settings.Indent = true;
                        XmlWriter wrt = XmlWriter.Create(saveFileDialog.FileName, settings);
                        wrt.WriteStartDocument();

                        wrt.WriteStartElement("Invoice");
                        wrt.WriteAttributeString("ID", invoiceID);
                        wrt.WriteElementString("Date", DateTime.Now.ToShortDateString());
                        wrt.WriteElementString("BuyerID", order.BuyerID);
                        wrt.WriteElementString("SellerID", Settings.SellerID);

                        wrt.WriteStartElement("Items");
                        foreach (OrderDetail detail in order.OrderDetails)
                        {
                            string newUnitPrice = DBManager.GetUnitPrice(detail.ItemID);
                            totalCost += Double.Parse(newUnitPrice);
                            totalQuantity += int.Parse(detail.Quantity);

                            wrt.WriteStartElement("Item");
                            wrt.WriteAttributeString("ID", detail.ItemID);
                            wrt.WriteElementString("Quantity", detail.Quantity);
                            wrt.WriteElementString("NewUnitPrice", newUnitPrice);
                            wrt.WriteEndElement();
                        }
                        wrt.WriteEndElement();

                        shippingCharges = calculateShippingCharges(totalQuantity);
                        totalCost += shippingCharges;
                        wrt.WriteElementString("ShippingCharges", shippingCharges.ToString());
                        wrt.WriteElementString("TotalCost", totalCost.ToString());

                        // close the file
                        wrt.WriteEndElement();
                        wrt.Flush();
                        wrt.Close();

                        if (DBManager.AddInvoice(invoiceID, order.OrderID))
                        {
                            MessageBox.Show("The invoice was successfully generated!", "Issue successful");
                        }
                        else
                        {
                            throw new Exception();
                        }
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("The invoice could not be generated.\nThis could be due to corruption in the database, a fault in database connection, or other issues.\n\nPlease check through the order to ensure that everything is proper.", "Invoice failed to generate");
                    }
                    return true;
                }
                else
                {
                    MessageBox.Show(invoiceErrorMsg, "Conflict encountered");
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        private string checkInvoice(string orderID, string invoiceID)
        {
            // this method does a check against the Invoice table
            // to ensure that the InvoiceID and OrderID are unique
            string result = "";
            if (!DBManager.CheckOrderID(orderID))
            {
                result += "An invoice has already been generated for this order.";
            }
            if (!DBManager.CheckInvoiceID(invoiceID))
            {
                if (result != "")
                {
                    result += "\nAlso, ";
                }
                result += "Invoice ID is already in use. Please enter another Invoice ID.";
            }
            return result;
        }

        private void generateRandomInvoiceID()
        {
            Random rdm = new Random();
            txtInvoiceID.Text = rdm.Next(9999).ToString();
        }

        private double calculateShippingCharges(int quantity)
        {
            if (quantity <= 100)
            {
                return quantity * 1;
            }
            else
            {
                return 100 + (quantity - 100) * 1.5;
            }
        }
    }
}
